package tianrun.ziguan.api.calculate.config.service.template.instance.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import tianrun.ziguan.api.calculate.config.dao.TEdgeInputInstanceMapper;
import tianrun.ziguan.api.calculate.config.dto.request.EdgeInputInstanceVO;
import tianrun.ziguan.api.calculate.config.dto.request.EdgeSourceLabelParam;
import tianrun.ziguan.api.calculate.config.dto.response.LabelNameBody;
import tianrun.ziguan.api.calculate.config.entity.TEdgeInputInstance;
import tianrun.ziguan.api.calculate.config.entity.TEdgeInputModule;
import tianrun.ziguan.api.calculate.config.entity.datainfo.TDatainfoAssetLine;
import tianrun.ziguan.api.calculate.config.entity.datainfo.TDatainfoLabelLine;
import tianrun.ziguan.api.calculate.config.enums.DeptAreaEnum;
import tianrun.ziguan.api.calculate.config.service.datainfo.TDatainfoAssetLineService;
import tianrun.ziguan.api.calculate.config.service.datainfo.TDatainfoLabelLineService;
import tianrun.ziguan.api.calculate.config.service.template.instance.ITEdgeInputInstanceService;
import tianrun.ziguan.api.calculate.config.service.template.module.ITEdgeInputModuleService;
import tianrun.ziguan.api.calculate.config.utils.StringUtil;
import tianrun.ziguan.api.common.core.resttemplate.IRestTemplateService;
import tianrun.ziguan.api.common.util.ListUtil;
import tianrun.ziguan.api.common.util.TokenUtil;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class TEdgeInputInstanceServiceImpl extends ServiceImpl<TEdgeInputInstanceMapper, TEdgeInputInstance> implements ITEdgeInputInstanceService {
    private final TDatainfoLabelLineService labelLineService;
    private final TDatainfoAssetLineService assetLineService;
    private final IRestTemplateService restTemplateService;
    private final ITEdgeInputModuleService edgeInputModuleService;
    private final String labelListUrl;
    private final String powerDeptUrl;

    public TEdgeInputInstanceServiceImpl(TDatainfoLabelLineService labelLineService, TDatainfoAssetLineService assetLineService, IRestTemplateService restTemplateService, ITEdgeInputModuleService edgeInputModuleService,
                                         @Value("${ziguan.control-config.api.labelList}") String labelListUrl,
                                         @Value("${ziguan.power.api.getDeptByDeptNum}") String powerDeptUrl) {
        this.labelLineService = labelLineService;
        this.assetLineService = assetLineService;
        this.restTemplateService = restTemplateService;
        this.edgeInputModuleService = edgeInputModuleService;
        this.labelListUrl = labelListUrl;
        this.powerDeptUrl = powerDeptUrl;
    }

    @Override
    public List<EdgeInputInstanceVO> listVOByTemplateIds(Set<Long> ids) {
        return baseMapper.listByTemplateIds(ids);
    }

    @Override
    public List<EdgeInputInstanceVO> listByModuleIds(Set<Long> ids) {
        return baseMapper.listByModuleIds(ids);
    }

    @Override
    public List<LabelNameBody> sourceLabelList(EdgeSourceLabelParam param){
        String token = TokenUtil.getToken();
        String deptStr = restTemplateService.get(String.format(powerDeptUrl,param.getDeptNum()),token);
        JSONObject deptObj = JSONObject.parseObject(deptStr);
        JSONObject deptBody = deptObj.getJSONObject("deptBody");
        Assert.isTrue((deptObj.containsKey("deptBody")&&deptBody.containsKey("data")),"该场缺少配置信息");
        JSONObject data = JSONObject.parseObject(deptBody.getString("data"));
        Boolean isHN = data.getBoolean("isHN");
        Assert.isTrue(Objects.nonNull(isHN),"慧能场判断失败");
        if (isHN){
            DeptAreaEnum area = DeptAreaEnum.getEnum(data.getString("CENTRAL_CONTROL_desc"));
            Assert.isTrue(Objects.nonNull(area),"场站大区判断失败");
            //调用control-config 的api
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deptNums", Lists.newArrayList(param.getDeptNum()));
            jsonObject.put("model",Lists.newArrayList(param.getModel()));
            jsonObject.put("activeTab","point_manage");
            jsonObject.put("currentPage",1);
            jsonObject.put("size",10000);
            jsonObject.put("area",area.getCode());
            jsonObject.put("hn",isHN);
            Assert.isTrue(StringUtil.isNotEmpty(token),"请传入token");
            String post = restTemplateService.post(labelListUrl,token , jsonObject);
            return JSONObject.parseObject(post).getJSONArray("data").toJavaList(LabelNameBody.class);
        }else{
            //访问data-info
            TDatainfoAssetLine assetLine = assetLineService.getByDeviceNum(param.getAssetNum());
            if(Objects.isNull(assetLine))return Collections.emptyList();
            List<TDatainfoLabelLine> labelLines = labelLineService.getByAssetLineId(assetLine.getId());
            return labelLines.stream().map(l -> LabelNameBody.of(l.getLabel(), l.getLabelName())).collect(Collectors.toList());
        }
    }

    @Override
    public void batchAdd(List<TEdgeInputInstance> list) {
        if (list.isEmpty()) {
            return;
        }
        Collection<TEdgeInputInstance> values = ListUtil.toMap(list, TEdgeInputInstanceServiceImpl::getKey, Function.identity()).values();
        list.clear();
        list.addAll(values);

        Map<Long, List<String>> moduleIdMap = ListUtil.groupList(list, TEdgeInputInstance::getModuleId, TEdgeInputInstance::getLabel);
        moduleIdMap.forEach((k, v) -> {
            if (v.isEmpty()) return;
            TEdgeInputModule module = edgeInputModuleService.getById(k);
            if (module==null)return;
            List<EdgeInputInstanceVO> haveInstances = listVOByTemplateIds(Sets.newHashSet(module.getTemplateId()));
            if (haveInstances.isEmpty())return;
            Map<String, TEdgeInputInstance> haveMap = ListUtil.toMap(haveInstances, TEdgeInputInstanceServiceImpl::getKey, e->e);
            list.stream().filter(i->haveMap.containsKey(getKey(i))).forEach(i->i.setId(haveMap.get(getKey(i)).getId()));
        });
        saveOrUpdateBatch(list);
    }

    private static String getKey(TEdgeInputInstance i) {
        return i.getModuleId() + ":" + i.getLabel();
    }
}
